﻿namespace Bootstrapper
{
    using System;
    using System.IO;
    using System.Windows.Forms;

    static class Program
    {
        private static AppDomain _domain;
        private static string _environmentPath;

        private static bool repeatExecution = false;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);

            string currVersion = "V1";

            _environmentPath = Environment.CurrentDirectory;
            _environmentPath = Path.Combine(_environmentPath, currVersion);
            //string cachePath = Path.Combine(environmentPath,"__cache");
            string configFile = Path.Combine(_environmentPath, "UpdateTest.exe.config");
            string assembly = GetExecutingAssemblyName();

            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = "UpdateTest";
            //setup.ShadowCopyFiles = "true";
            //setup.CachePath = cachePath;
            setup.ConfigurationFile = configFile;

            //_domain = AppDomain.CurrentDomain;
            // Anwendungsdomäne erstellen:
            _domain = AppDomain.CreateDomain(
                "Sample",
                AppDomain.CurrentDomain.Evidence,
                setup);

            _domain.AssemblyResolve += Domain_AssemblyResolve;
            _domain.UnhandledException += Domain_UnhandledException;
            _domain.TypeResolve += Domain_TypeResolve;
            ExecuteApplication(assembly);
        }

        private static string GetExecutingAssemblyName()
        {
            return Path.Combine(_environmentPath, "UpdateTest.exe");
        }

        private static bool ExecuteApplication(string assembly)
        {
            bool ret = true;
            do
            {
                repeatExecution = false;
                try
                {
                    _domain.ExecuteAssembly(assembly);
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            } 
            while (repeatExecution);

            return ret;
        }

        private static void HandleException(Exception e)
        {
            DialogResult dialogResult = MessageBox.Show(
                string.Format("Unhandled exception happend {0}"+
                "\n\n Do you want to restart application?", e),
                "Error happend",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Error);
            if (dialogResult == DialogResult.Yes)
            {
                repeatExecution = true;
            }
        }

        static System.Reflection.Assembly Domain_TypeResolve(object sender, ResolveEventArgs args)
        {
            return null;
        }

        static void Domain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            HandleException((Exception) e.ExceptionObject);
        }

        static System.Reflection.Assembly Domain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            return null;
        }
    }
}
